package com.tqjc.work.impl;


import com.tqjc.consts.WorkConst;
import com.tqjc.entity.*;
import com.tqjc.service.TaskService;
import com.tqjc.system.core.util.SpringUtils;
import com.tqjc.work.CraneWork;
import com.tqjc.work.TaskStatus;
import com.tqjc.work.ThreadPoolOperator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class CraneWorkImpl implements CraneWork {

    @Resource
    TaskService taskService;

    @Resource
    TaskStatus taskStatus;


    private volatile Boolean onlineWorking = false;

    private volatile Boolean offlineWorking = false;
    private volatile Boolean splitFlowWorking = false;

    //存储现在正在运行的线程
    public Runnable nowThread = null;



    @Override
    public void stopOfflineWork() {
        try {
            setOfflineWorking(false);
            if (nowThread != null) {
                ThreadPoolOperator.getInstance().interruptWorkThread(nowThread);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void stopOnlineWork() {
        try {
            setOnlineWorking(false);
            if (nowThread != null) {
                ThreadPoolOperator.getInstance().interruptWorkThread(nowThread);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void stopSplitFlowWork() {
        try {
            setSplitFlowWorking(false);
            if (nowThread != null) {
                ThreadPoolOperator.getInstance().interruptWorkThread(nowThread);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public PublicResult splitFlowStartWork(String splitFlowPath) {
        this.splitFlowWorking = true;
        Runnable craneWorkRunnable = () -> {
            try {
                //当标志位为true时，持续执行任务
                while (splitFlowWorking) {
                    try {
                        //生成任务
                        Task task = getSplitFlowTask(splitFlowPath);
                        if (task == null) {
                            task=getBackTask();
                        }
                        if (task != null) {
                            //设置任务开始时间
                            task.setBeginTime(new Date());
                            task = taskService.insert(task);
                            //根据任务获取当前任务的所有步骤
                            PublicResult<List<TaskApart>> stepResult = getStepsByTask(task);
                            //如果生成成功,分配任务准备执行
                            if (stepResult.isSuccess()) {
                                //修改工作状态
                                WorkStatus workStatus = taskStatus.getWorkStatus4Crane();
                                workStatus.setNowTask(task.getType());
                                workStatus.setNowStatus("运行中");
                                taskStatus.setWorkStatus4Crane(workStatus);

                                List<TaskApart> taskApartList = stepResult.getData();
                                for (TaskApart taskApart : taskApartList) {
                                    taskApart.setTaskApartByTask(task);
                                    taskApart.action();
                                }
                            }

                            task.setEndTime(new Date());
                            taskService.saveOrUpdate(task);
                            taskStatus.setTaskStatus4Crane("");

                        }
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        log.error(e.getMessage(),e);
                        e.printStackTrace();
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage(),e);
                e.printStackTrace();
            }
        };
        setNowThread(craneWorkRunnable);
        ThreadPoolOperator.getInstance().submitWorkThread(craneWorkRunnable);
        return PublicResult.ok("启动成功");
    }
    @Override
    public PublicResult offlineStartWork(String offlinePath) {
        this.offlineWorking = true;
        Runnable craneWorkRunnable = () -> {
            try {
                //当标志位为true时，持续执行任务
                while (offlineWorking) {
                    try {
                        //生成任务
                        Task task = getOfflineTask(offlinePath);
                        if (task == null) {
                            task=getBackTask();
                        }
                        if (task != null) {
                            //设置任务开始时间
                            task.setBeginTime(new Date());
                            task = taskService.insert(task);
                            //根据任务获取当前任务的所有步骤
                            PublicResult<List<TaskApart>> stepResult = getStepsByTask(task);
                            //如果生成成功,分配任务准备执行
                            if (stepResult.isSuccess()) {
                                //修改工作状态
                                WorkStatus workStatus = taskStatus.getWorkStatus4Crane();
                                workStatus.setNowTask(task.getType());
                                workStatus.setNowStatus("运行中");
                                taskStatus.setWorkStatus4Crane(workStatus);

                                List<TaskApart> taskApartList = stepResult.getData();
                                for (TaskApart taskApart : taskApartList) {
                                    taskApart.setTaskApartByTask(task);
                                    taskApart.action();
                                }
                            }

                            task.setEndTime(new Date());
                            taskService.saveOrUpdate(task);
                            taskStatus.setTaskStatus4Crane("");

                        }
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        log.error(e.getMessage(),e);
                        e.printStackTrace();
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage(),e);
                e.printStackTrace();
            }
        };
        setNowThread(craneWorkRunnable);
        ThreadPoolOperator.getInstance().submitWorkThread(craneWorkRunnable);
        return PublicResult.ok("启动成功");
    }
    @Override
    public PublicResult onlineStartWork(String onlinePath) {
        this.onlineWorking = true;


        Runnable craneWorkRunnable = () -> {
            try {
                //当标志位为true时，持续执行任务
                while (onlineWorking) {
                    try {
                        //生成任务
                        Task task = getOnlineTask(onlinePath);
                        if (task == null) {
                            task=getBackTask();
                        }
                        if (task != null) {
                            //设置任务开始时间
                            task.setBeginTime(new Date());
                            task = taskService.insert(task);
                            //根据任务获取当前任务的所有步骤
                            PublicResult<List<TaskApart>> stepResult = getStepsByTask(task);
                            //如果生成成功,分配任务准备执行
                            if (stepResult.isSuccess()) {
                                //修改工作状态
                                WorkStatus workStatus = taskStatus.getWorkStatus4Crane();
                                workStatus.setNowTask(task.getType());
                                workStatus.setNowStatus("运行中");
                                taskStatus.setWorkStatus4Crane(workStatus);

                                List<TaskApart> taskApartList = stepResult.getData();
                                for (TaskApart taskApart : taskApartList) {
                                    taskApart.setTaskApartByTask(task);
                                    taskApart.action();
                                }
                            }

                            task.setEndTime(new Date());
                            taskService.saveOrUpdate(task);
                            taskStatus.setTaskStatus4Crane("");

                        }
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        log.error(e.getMessage(),e);
                        e.printStackTrace();
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage(),e);
                e.printStackTrace();
            }
        };
        setNowThread(craneWorkRunnable);
        ThreadPoolOperator.getInstance().submitWorkThread(craneWorkRunnable);
        return PublicResult.ok("启动成功");
    }

    private Task getSplitFlowTask(String splitFlowPath){
        Task task=new Task();
        SplitFlowPathEnum splitFlowPathEnum=null;
        if("1".equals(splitFlowPath)){
            splitFlowPathEnum= SplitFlowPathEnum.splitFlowPath1;
        }else if("2".equals(splitFlowPath)){
            splitFlowPathEnum= SplitFlowPathEnum.splitFlowPath2;
        }
        RollerEnum rollerFrom=splitFlowPathEnum.getRollerFrom();
        RollerEnum rollerTo=splitFlowPathEnum.getRollerTo();
        //TODO 一级辊道PLC获取辊道钢板就位信号
        boolean rollerSteelSignal=true;
        if(rollerSteelSignal){
            //TODO 一级辊道PLC，获取另一边辊道空位信号
            boolean isEmpty=true;
            if(isEmpty){
                //TODO  从二级辊道系统获取钢板组合及钢板号
                String steelNos="";
                int combType=2;
                task.setSteelNos(steelNos);
                task.setType("offline");
                task.setBeginX(rollerFrom.getX());
                task.setBeginY(rollerFrom.getY());
                task.setBeginZ(rollerFrom.getZ());
                task.setEndX(rollerTo.getX());
                task.setEndY(rollerTo.getY());
                task.setEndZ(rollerTo.getZ());
                task.setRollerId(rollerTo.getId());
                task.setStockId(rollerTo.getId());
            }else {
                return null;
            }
        }else {
            return null;
        }
        return task;
    }
    private Task getOfflineTask(String offlinePath){
        Task task=new Task();
        OfflinePathEnum offlinePathEnum=null;
        if("1".equals(offlinePath)){
            offlinePathEnum= OfflinePathEnum.offlinePath1;
        }else if("2".equals(offlinePath)){
            offlinePathEnum= OfflinePathEnum.offlinePath2;
        }else if("3".equals(offlinePath)){
            offlinePathEnum= OfflinePathEnum.offlinePath3;
        }else if("4".equals(offlinePath)){
            offlinePathEnum= OfflinePathEnum.offlinePath4;
        }
        StockEnum stockEnum=offlinePathEnum.getStock();
        RollerEnum rollerEnum=offlinePathEnum.getRoller();
        //TODO 一级辊道PLC获取辊道钢板就位信号
        boolean rollerSteelSignal=true;
        if(rollerSteelSignal){
            //TODO 判断数据库中垛位上钢板高度是否超高
            boolean isOverHeight=false;
            if(!isOverHeight){
                //TODO  从二级辊道系统获取钢板组合及钢板信息    以及从数据库中获取最上层钢板信息
                //TODO 判断要放板子长度是否大于最上层钢板，要放钢板组合的1/2是否小于最上层板子
                String steelNos="";
                int combType=2;
                task.setSteelNos(steelNos);
                task.setType("offline");
                task.setBeginX(rollerEnum.getX());
                task.setBeginY(rollerEnum.getY());
                task.setBeginZ(rollerEnum.getZ());
                task.setEndX(stockEnum.getX());
                task.setEndY(stockEnum.getY());
                task.setEndZ(stockEnum.getZ());   //TODO Z加上垛位的高度
                task.setRollerId(rollerEnum.getId());
                task.setStockId(stockEnum.getId());
            }else {
                return null;
            }
        }else {
            return null;
        }
        return task;
    }


    private Task getOnlineTask(String onlinePath){
        Task task=new Task();
        OnlinePathEnum onlinePathEnum = OnlinePathEnum.getEnumByPath(onlinePath);
        StockEnum stockEnum = onlinePathEnum.getStock();
        RollerEnum rollerEnum = onlinePathEnum.getRoller();
        //TODO 一级辊道PLC获取辊道空位信号
        boolean rollerEmpty=true;
        if(rollerEmpty){
            //TODO 判断数据库中垛位是否有钢板
            boolean hasSteels=true;
            if(hasSteels){
                //TODO  从数据库中获取垛位最上层钢板信息
                int combType=1;
                String steelNos="";
                task.setSteelNos(steelNos);
                task.setType("online");
                task.setBeginX(stockEnum.getX());
                task.setBeginY(stockEnum.getY());
                task.setBeginZ(stockEnum.getZ()); //TODO Z加上垛位的高度
                task.setEndX(rollerEnum.getX());
                task.setEndY(rollerEnum.getY());
                task.setEndZ(rollerEnum.getZ());
                task.setRollerId(rollerEnum.getId());
                task.setStockId(stockEnum.getId());
            }else {
                return null;
            }
        }else {
            return null;
        }
        return task;
    }



    public Task getBackTask() {
        //创建新的Task任务
        Task task = new Task();
        task.setType("move");
        //设置移动目标位置为默认位置
        task.setBeginX(WorkConst.BERTHLOCATIONX);
        task.setBeginY(WorkConst.BERTHLOCATIONY);
        task.setBeginZ(WorkConst.BERTHLOCATIONZ);

        //设置当前任务钢板号

        //设置放板点为垛位
        task.setEndX(WorkConst.BERTHLOCATIONX);
        task.setEndY(WorkConst.BERTHLOCATIONY);
        task.setEndZ(WorkConst.BERTHLOCATIONZ);
        return task;
    }



    @Override
    public PublicResult<List<TaskApart>> getStepsByTask(Task task) {
        List<String> stepList=new ArrayList<>();
        if("move".equals(task.getType())){
            stepList.add("moveCraneStep");
        }else if("online".equals(task.getType())){
            stepList.add("onlineSuckStep");
            stepList.add("onlinePlaceStep");
        }else if("offline".equals(task.getType())){
            stepList.add("offlineSuckStep");
            stepList.add("offlinePlaceStep");
        }else if("splitFlow".equals(task.getType())){
            stepList.add("splitFlowSuckStep");
            stepList.add("splitFlowPlaceStep");
        }

        List<TaskApart> taskAparts = new ArrayList<>();
        for (String datum : stepList) {
            try {
                //获取对应的对象
                TaskApart taskApart = SpringUtils.getBean(datum);
                taskAparts.add(taskApart);
            } catch (Exception e) {
                e.printStackTrace();
                return PublicResult.fail("failed");
            }
        }
        return PublicResult.ok(taskAparts);
    }

    @Override
    public Runnable getNowThread() {
        return this.nowThread;
    }

    @Override
    public void setNowThread(Runnable runnable) {
        this.nowThread = runnable;

    }

    @Override
    public Boolean getOnlineWorking() {
        return onlineWorking;
    }
    @Override
    public void setOnlineWorking(Boolean onlineWorking) {
        this.onlineWorking = onlineWorking;
    }
    @Override
    public Boolean getOfflineWorking() {
        return offlineWorking;
    }
    @Override
    public void setOfflineWorking(Boolean offlineWorking) {
        this.offlineWorking = offlineWorking;
    }
    @Override
    public Boolean getSplitFlowWorking() {
        return splitFlowWorking;
    }
    @Override
    public void setSplitFlowWorking(Boolean splitFlowWorking) {
        this.splitFlowWorking = splitFlowWorking;
    }

    @Override
    public PublicResult offlineStopWork(String offlinePath) {
        return null;
    }

    @Override
    public PublicResult splitFlowStopWork(String splitFlowPath) {
        return null;
    }

    public static void main(String[] args) {
        Runnable rr=()->{
            for (int i = 0; i < 20; i++) {
                System.out.println("now print "+i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("thread rr is over");
        };
        ThreadPoolOperator.getInstance().submitWorkThread(rr);
        try {
            Thread.sleep(8000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("thread main is over");
        ThreadPoolOperator.getInstance().interruptWorkThread(rr);
    }
}
